package com.base.common.util;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.text.StringCharacterIterator;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.compile;

/**
 * @author admin
 * @date 2020/5/19 AM10:15
 */
@SuppressWarnings("ALL")
@Slf4j
public class StringUtil {

    private StringUtil() {
    }

    protected static ResourceBundle resourceBundle = null;
    public static final String BUNDLE_KEY = "ApplicationResources";

    /**
     * 即将开始商品隐藏秒杀价
     */
    public static String hideSeckillPrice(Object seckillPrice) {
        String seckillPriceStr = StringUtil.null2Str(seckillPrice);
        try {
            if (seckillPriceStr.length() == 1) {
                return seckillPriceStr;
            } else {
                int index = seckillPriceStr.indexOf('.');
                if (index >= 0) {
                    //含小数
                    //整数部分
                    String frontStr = seckillPriceStr.substring(0, index);
                    //小数部分
                    String smallStr = seckillPriceStr.substring(index);

                    if (frontStr.length() == 1) {
                        return seckillPriceStr;
                    } else {
                        StringBuilder hideBul = new StringBuilder();
                        int length = frontStr.length() - 1;
                        for (int i = 0; i < length; i++) {
                            hideBul.append("?");
                        }
                        hideBul.append(frontStr.substring(frontStr.length() - 1));
                        hideBul.append(smallStr);
                        return hideBul.toString();
                    }
                } else {
                    //整数
                    StringBuilder hideBul = new StringBuilder();
                    int length = seckillPriceStr.length() - 1;
                    for (int i = 0; i < length; i++) {
                        hideBul.append("?");
                    }
                    hideBul.append(seckillPriceStr.substring(seckillPriceStr.length() - 1));
                    return hideBul.toString();
                }
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return seckillPriceStr;
    }

    /**
     * double比较在两个double之间
     *
     * @param oneDouble
     * @param towDouble
     * @param differDouble
     * @return
     */
    public static boolean doubleTowValueBetween(Double oneDouble, Double towDouble, Double differDouble) {
        try {
            oneDouble = StringUtil.nullToDouble(oneDouble);
            towDouble = StringUtil.nullToDouble(towDouble);
            differDouble = StringUtil.nullToDouble(differDouble);
            if (oneDouble.compareTo(0.0D) > 0
                    && towDouble.compareTo(0.0D) > 0
                    && differDouble.compareTo(0.0D) > 0) {
                if (oneDouble.compareTo(towDouble) == 0) {
                    // 比较两值相对
                    return true;
                } else if (oneDouble.compareTo(towDouble) > 0) {
                    Double differValue = StringUtil.nullToDouble(oneDouble - towDouble);
                    if (differDouble.compareTo(differValue) >= 0) {
                        // 比较范围值要小
                        return true;
                    }
                } else {
                    Double differValue = StringUtil.nullToDouble(towDouble - oneDouble);
                    if (differDouble.compareTo(differValue) >= 0) {
                        // 比较范围值要小
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return false;
    }

    /**
     * 自动唯一值
     *
     * @return
     */
    public static String getRandomUUID() {
        String randomUUID = UUID.randomUUID().toString();
        return randomUUID.replace("-", "");
    }

    /**
     * 对象转换Map
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map<String, Object> objectToMap(Object obj) {
        if (obj == null) {
            return null;
        }

        Map<String, Object> map = null;
        try {
            map = new HashMap<>();
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();
                if (key.compareToIgnoreCase("class") == 0) {
                    continue;
                }

                Method getter = property.getReadMethod();
                Object value = getter != null ? getter.invoke(obj) : null;
                map.put(key, value);
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return map;
    }

    /**
     * 比较两个值是否相等
     *
     * @param objOne
     * @param objTow
     * @return
     */
    public static boolean compareObject(Object objOne, Object objTow) {
        return StringUtil.null2Str(objOne).equalsIgnoreCase(StringUtil.null2Str(objTow));
    }

    /**
     * 比较两个值是否相等
     *
     * @param objOne
     * @param objTow
     * @return int;符合为1,不符合为0
     */
    public static int compareObjectToInt(Object objOne, Object objTow) {
        return StringUtil.compareObject(objOne, objTow) ? Integer.valueOf(1) : Integer.valueOf(0);
    }

    /**
     * 判断是否为合法的日期时间字符串
     *
     * @param str_input
     * @return boolean;符合为true,不符合为false
     */
    public static boolean isDate(String string, String rDateFormat) {
        if (!isNull(string)) {
            SimpleDateFormat formatter = new SimpleDateFormat(rDateFormat);
            formatter.setLenient(false);
            try {
                formatter.format(formatter.parse(string));
            } catch (Exception e) {
                return false;
            }
            return true;
        }
        return false;
    }

    public static boolean isNull(String str) {
        if (str == null) {
            return true;
        } else if ("".equals(str.trim())) {
            return true;
        } else {
            return "null".equals(str.trim());
        }
    }

    public static boolean isEachNull(List<String> list) {
        for (String each : list) {
            if (isNull(each)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isNull(Object str) {
        if (str == null) {
            return true;
        } else if ("".equals(str.toString())) {
            return true;
        } else {
            return "null".equals(str.toString());
        }
    }

    public static boolean isAllNull(String... strs) {
        if (strs == null || strs.length == 0) {
            return true;
        } else {
            String[] var1 = strs;
            int var2 = strs.length;

            for (int var3 = 0; var3 < var2; ++var3) {
                String str = var1[var3];
                if (!isNull(str)) {
                    return false;
                }
            }
            return true;
        }
    }

    public static boolean isAllNull(Object... strs) {
        if (strs == null || strs.length == 0) {
            return true;
        } else {
            Object[] var1 = strs;
            int var2 = strs.length;

            for (int var3 = 0; var3 < var2; ++var3) {
                Object str = var1[var3];
                if (!isNull(str)) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 将NULL转换成空字符串
     *
     * @param value
     * @return
     */
    public static String null2Str(Object value) {
        return value == null || "null".equals(value.toString()) ? "" : value.toString().trim();
    }

    public static String null2Str(String value) {
        return value == null || "null".equals(value) ? "" : value.trim();
    }

    public static String nullToString(String value) {
        return value == null || "null".equals(value) ? "" : value.trim();
    }

    public static String nullToString(Object value) {
        return value == null ? "" : value.toString().trim();
    }

    /**
     * 将姓名中包含点的替换成正确格式的点
     *
     * @param value
     * @return
     */
    public static String dotStrFormat(String value) {
        String valueStr = StringUtil.null2Str(value);
        List<String> strList = new ArrayList<>();
        strList.add("·");
        strList.add("•");
        strList.add(".");
        for (String str : strList) {
            if (valueStr.contains(str)) {
                valueStr = valueStr.replace(str, "·");
            }
        }
        return valueStr;
    }

    public static Long nullToLong(Object value) {
        return value == null || "null".equals(value.toString()) ? 0L : stringToLong(value.toString());
    }

    public static Integer nullToInteger(Object value) {
        return value == null || "null".equals(value.toString()) ? 0 : stringToInteger(value.toString());
    }

    public static Byte nullToByte(Object value) {
        return value == null || "null".equals(value.toString()) ? Byte.valueOf("0") : stringToByte(value.toString());
    }

    public static List<String> nullArrayToList(String[] strArrays) {
        List<String> arrayList = new ArrayList<>();
        if (strArrays != null && strArrays.length > 0) {
            for (int i = 0; i < strArrays.length; i++) {
                arrayList.add(StringUtil.null2Str(strArrays[i]));
            }
        }
        return arrayList;
    }

    public static Double addDouble(Double value1, Double value2) {
        BigDecimal b1 = new BigDecimal(nullToString(value1));
        BigDecimal b2 = new BigDecimal(nullToString(value2));
        return StringUtil.nullToDoubleFormat(String.valueOf(b1.add(b2)));
    }

    /**
     * 向上取整，1=向下取整
     *
     * @param value
     * @param type
     * @return
     */
    public static String getIntegerNumberStr(Object value, int type) {
        Double val = StringUtil.nullToDoubleFormat(value);
        try {
            if (type == 1) {
                val = Math.floor(val);
            } else {
                val = Math.ceil(val);
            }
            return StringUtil.null2Str(StringUtil.nullToDouble(val).intValue());
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return StringUtil.nullToDoubleFormatStr(val);
    }

    public static Double nullToDouble(Object value) {
        if (!isNull(value)) {
            if (value instanceof Double) {
                return (Double) value;
            } else {
                try {
                    return Double.parseDouble(nullToString(value));
                } catch (NumberFormatException e) {
                    log.error("exception: {}", e);
                }
            }
        }
        return 0D;
    }

    /**
     * 保留两位小数
     *
     * @param value
     * @return
     */
    public static String nullToDoubleFormatDecimal(Object value) {
        try {
            DecimalFormat df = new DecimalFormat("0.00");
            return StringUtil.null2Str(df.format(StringUtil.nullToDoubleFormat(value)));
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return StringUtil.null2Str(StringUtil.nullToDoubleFormat(value));
    }

    public static String nullToDoubleFormatStr(Object value) {
        return StringUtil.null2Str(StringUtil.nullToDoubleFormat(value));
    }

    /**
     * 订单金额转换成分
     *
     * @param doubleValue
     * @return
     */
    public static Integer doubleToBranchInt(Double doubleValue) {
        try {
            BigDecimal bigDecimal1 = new BigDecimal(Double.toString(100));
            BigDecimal bigDecimal2 = new BigDecimal(Double.toString(doubleValue));
            return bigDecimal1.multiply(bigDecimal2).intValue();
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return 0;
    }

    public static Double nullToDoubleFormat(Object value) {
        try {
            double d = StringUtil.nullToDouble(value);
            //保留两位小数，如果不需要四舍五入，可以使用RoundingMode.DOWN
            //使用double作为构造函数， 不够精确，需使用string
            BigDecimal bigDecimal = BigDecimal.valueOf(d).setScale(2, RoundingMode.UP);
            return bigDecimal.doubleValue();
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return 0D;
    }

    /**
     * 超过万元以上的以 2.34万格式显示
     *
     * @param price
     * @return
     */
    public static String formatAmount(String price, String unit) {
        BigDecimal bigDecimal1 = new BigDecimal(price);
        BigDecimal bigDecimal2 = new BigDecimal(unit);
        if (bigDecimal1.compareTo(bigDecimal2) < 0) {
            return StringUtil.null2Str(price);
        }
        // 转换为万元（除以10000）
        BigDecimal decimal = bigDecimal1.divide(new BigDecimal("10000"));
        String value = decimal.toString();
        //刚好整除
        if (value.indexOf('.') == -1) {
            return StringUtil.null2Str(value + "w");
        }

        // 保留两位小数
        DecimalFormat formater = new DecimalFormat("0.00");
        // 四舍五入
        formater.setRoundingMode(RoundingMode.FLOOR);
        // 格式化完成之后得出结果
        String formatNum = formater.format(decimal) + "w";
        return StringUtil.null2Str(formatNum);
    }

    public static Float nullToFloat(Object value) {
        if (!isNull(value)) {
            if (value instanceof Float) {
                return (Float) value;
            } else {
                try {
                    return Float.parseFloat(nullToString(value));
                } catch (NumberFormatException e) {
                    log.error("exception: {}", e);
                }
            }
        }
        return 0F;
    }

    public static Boolean nullToBoolean(Object value) {
        if (value == null
                || "null".equals(value.toString())) {
            return false;
        }
        if (!"1".equals(value.toString().trim())
                && !"true".equalsIgnoreCase(value.toString().trim())
                && !"是".equalsIgnoreCase(value.toString().trim())) {
            return false;
        }
        return true;
    }

    public static Integer booleanToInt(Boolean value) {
        if (StringUtil.nullToBoolean(value)) {
            return 1;
        }
        return 0;
    }

    public static Long stringToLong(String value) {
        Long l;
        value = nullToString(value);
        if ("".equals(value)) {
            l = 0L;
        } else {
            try {
                l = Long.valueOf(value);
            } catch (Exception e) {
                l = 0L;
            }
        }
        return l;
    }

    public static Integer stringToInteger(String value) {
        Integer l;
        value = nullToString(value);
        if ("".equals(value)) {
            l = 0;
        } else {
            try {
                l = Integer.valueOf(value);

            } catch (Exception e) {
                l = 0;
            }
        }
        return l;
    }

    public static Byte stringToByte(String value) {
        Byte l;
        value = nullToString(value);
        if ("".equals(value)) {
            l = 0;
        } else {
            try {
                l = Byte.valueOf(value);

            } catch (Exception e) {
                l = 0;
            }
        }
        return l;
    }

    public static String integerToString(Integer value) {
        if (value == null) {
            return "0";
        }

        return value.toString();
    }

    public static List<Long> stringToLongArray(String value) {
        List<Long> ls = new ArrayList<>();
        try {
            if (value == null || "".equals(value)) {
                return ls;
            }

            String[] ids = value.split(",");
            for (int i = 0; i < ids.length; i++) {
                if (!ls.contains(Long.parseLong(ids[i])) && isNumber(ids[i])) {
                    ls.add(Long.parseLong(ids[i]));
                }
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return ls;
    }

    public static List<String> stringToStrArray(String value) {
        List<String> ls = new ArrayList<>();
        try {
            if (value == null || "".equals(value)) {
                return ls;
            }

            String[] ids = value.split(",");
            for (int i = 0; i < ids.length; i++) {
                if (!ls.contains(ids[i])) {
                    ls.add(StringUtil.null2Str(ids[i]));
                }
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return ls;
    }

    public static List<Integer> stringToIntegerArray(String value) {
        List<Integer> ls = new ArrayList<>();
        try {
            if (value == null || "".equals(value)) {
                return ls;
            }

            String[] ids = value.split(",");
            for (int i = 0; i < ids.length; i++) {
                if (isNumber(ids[i])) {
                    ls.add(Integer.parseInt(ids[i]));
                }
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return ls;
    }

    public static Set<Long> stringToIntegerSet(String value) {
        Set<Long> set = new HashSet<>();
        if (value == null || "".equals(value)) {
            return set;
        }

        String[] ids = value.split(",");
        for (int i = 0; i < ids.length; i++) {
            if (isNumber(ids[i])) {
                set.add(Long.parseLong(ids[i]));
            }
        }
        return set;
    }

    public static Set<String> stringToStrSet(String value) {
        Set<String> set = new HashSet<>();
        if (value == null || "".equals(value)) {
            return set;
        }

        String[] ids = value.split(",");
        for (int i = 0; i < ids.length; i++) {
            if (!StringUtil.isNull(ids[i])) {
                set.add(StringUtil.null2Str(ids[i]));
            }
        }
        return set;
    }

    public static String longArrayToString(List<Long> value) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return null;
        }

        for (Iterator<Long> it = value.iterator(); it.hasNext(); ) {
            sb.append(it.next());
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static String stringArrayToString(List<String> existMobileList) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(existMobileList)) {
            return null;
        }

        for (Iterator<String> it = existMobileList.iterator(); it.hasNext(); ) {
            sb.append(it.next());
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static String longArray2String(List<Long> value) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return null;
        }

        for (Iterator<Long> it = value.iterator(); it.hasNext(); ) {
            sb.append("'" + it.next() + "'");
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static String intArrayToString(List<Integer> value) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return null;
        }

        for (Iterator<Integer> it = value.iterator(); it.hasNext(); ) {
            sb.append(null2Str(it.next()));
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static Long stringToLong(Object value) {
        Long l;
        value = nullToString(value);
        if ("".equals(value)) {
            l = 0L;
        } else {
            try {
                l = Long.valueOf(value.toString());
            } catch (Exception e) {
                l = 0L;
            }
        }
        return l;
    }

    public static List<Long> longSetToList(Set<Long> value) {
        List<Long> list = new ArrayList<>();
        if (CollectionUtil.isEmpty(value)) {
            return list;
        }

        for (Iterator<Long> it = value.iterator(); it.hasNext(); ) {
            list.add(it.next());
        }
        return list;
    }

    public static String longSetToStr(Set<Long> value) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return "";
        }

        for (Iterator<Long> it = value.iterator(); it.hasNext(); ) {
            sb.append(null2Str(it.next()));
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static String longListToStr(List<Long> value) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return "";
        }

        for (Iterator<Long> it = value.iterator(); it.hasNext(); ) {
            sb.append(null2Str(it.next()));
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static List<Integer> integerSetToList(Set<Integer> value) {
        List<Integer> list = new ArrayList<>();
        if (CollectionUtil.isEmpty(value)) {
            return list;
        }

        for (Iterator<Integer> it = value.iterator(); it.hasNext(); ) {
            list.add(it.next());
        }
        return list;
    }

    public static String strSetToString(Set<String> value) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return sb.toString();
        }

        for (Iterator<String> it = value.iterator(); it.hasNext(); ) {
            sb.append(it.next());
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static String strListToString(List<String> value) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return sb.toString();
        }

        for (Iterator<String> it = value.iterator(); it.hasNext(); ) {
            sb.append(it.next());
            if (it.hasNext()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    public static String strListToString(List<String> value, String splitChar) {
        StringBuilder sb = new StringBuilder();
        if (CollectionUtil.isEmpty(value)) {
            return sb.toString();
        }

        for (Iterator<String> it = value.iterator(); it.hasNext(); ) {
            sb.append(it.next());
            if (it.hasNext()) {
                sb.append(splitChar);
            }
        }
        return sb.toString();
    }

    public static List<String> strSetToList(Set<String> value) {
        List<String> list = new ArrayList<>();
        if (CollectionUtil.isEmpty(value)) {
            return list;
        }

        for (Iterator<String> it = value.iterator(); it.hasNext(); ) {
            list.add(it.next());
        }
        return list;
    }

    public static List<String> strToStrList(String value, String splitChar) {
        List<String> list = new ArrayList<>();
        if (StringUtil.isNull(value)) {
            return list;
        }

        String[] strArray = value.split(splitChar);
        for (int i = 0; i < strArray.length; i++) {
            if (!StringUtil.isNull(strArray[i])) {
                list.add(strArray[i].trim());
            }
        }
        return list;
    }

    /**
     * 判断字符串是否是整数
     */
    public static boolean isInteger(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    public static int parseInteger(String value) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    /**
     * 判断字符串是否是浮点数
     */
    public static boolean isDouble(String value) {
        try {
            Double d = Double.parseDouble(value);
            String tempD = d.toString();
            return tempD.contains(".");
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 判断字符串是否是数字
     */
    public static boolean isNumber(String value) {
        if (isNull(value)) {
            return false;
        }
        return isInteger(value) || isDouble(value);
    }

    public static boolean isNumber(Object value) {
        if (isNull(value)) {
            return false;
        }
        return isInteger(nullToString(value)) || isDouble(nullToString(value));
    }

    /**
     * 判断是否为时间 *
     */
    public static boolean isDate(String value) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            sdf.parse(value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 中文转换--文章换行的转换
     *
     * @param str
     * @return
     */
    public static String getChinseText(String str) {
        if (str == null) {
            return ("");
        }
        if (str.equals("")) {
            return ("");
        }
        // 建立一个StringBuilder来处理输入数据
        StringBuilder buf = new StringBuilder(str.length() + 6);
        char ch;
        for (int i = 0; i < str.length(); i++) {
            ch = str.charAt(i);
            if (ch == '\r') {
                buf.append(" ");
            } else if (ch == '\n') {
                buf.append(" ");
            } else if (ch == '\t') {
                buf.append("    ");
            } else if (ch == ' ') {
                buf.append(" ");
            } else if (ch == '\'') {
                buf.append("\\'");
            } else {
                buf.append(ch);
            }
        }
        return buf.toString();
    }

    /**
     * 清除所有特殊字符，只保留中英文字符和数字
     *
     * @param str
     * @return
     */
    public static String getEscapeTextTmp(String str) {
        try {
            String regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";
            Pattern p = compile(regEx);
            Matcher m = p.matcher(str);
            return m.replaceAll("");
        } catch (Exception e) {
            log.error("exception: {}", e);
            return null;
        }
    }

    /**
     * 清除所有特殊字符，只保留中英文字符和数字
     *
     * @param str
     * @return
     */
    public static boolean isEscapeText(String str) {
        boolean flag = false;
        try {
            String regEx = "[`~!@#$%^&*()+=|{}':;',…\\[\\].<>/?~！@#￥%…&*（）——+|{}【】‘；：”“’。，、？]";
            Pattern p = compile(regEx);
            Matcher m = p.matcher(str);
            if (m.find()) {
                flag = true;
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return flag;
    }

    /**
     * 判断字符串中是否包含除中英文字符和数字外的特殊字符，包含返回true
     *
     * @param str
     * @return
     */
    public static boolean haveEscapeText(String str) {
        if (str.replaceAll("[\u4e00-\u9fa5]*[a-z]*[A-Z]*\\d*-*_*\\s*", "").length() != 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * java判断是否为全汉字
     *
     * @param str
     * @return
     */
    public static boolean isChineseCharacters(String str) {
        String pointReg = "[\\u4e00-\\u9fa5]+[·•][\\u4e00-\\u9fa5]+";
        String reg = "[\\u4e00-\\u9fa5]+";
        if (str.contains("·") || str.contains("•")) {
            if (!str.matches(pointReg)) {
                return false;
            } else {
                return true;
            }
        } else {
            if (!str.matches(reg)) {
                return false;
            } else {
                return true;
            }
        }
    }

    /**
     * 判断价格
     *
     * @param str
     * @return
     */
    public static boolean isPrice(String str) {
        String reg = "[\\d]{1,3}|[\\d]{1,3}\\.[\\d]{1,2}";
        if (StringUtil.isNull(str) || !StringUtil.null2Str(str).matches(reg)) {
            return false;
        }
        return true;
    }

    /**
     * 判断重量
     *
     * @param str
     * @return
     */
    public static boolean isWeigth(String str) {
        String reg = "[\\d]{1,4}|[\\d]{1,4}\\.[\\d]{1}";
        if (StringUtil.isNull(str) || !StringUtil.null2Str(str).matches(reg)) {
            return false;
        }
        return true;
    }

    /**
     * java判断是否是只有一个汉字
     *
     * @param str
     * @return
     */
    public static boolean isOneChineseCharacters(String str) {
        String reg = "[\\u4e00-\\u9fa5]{1}";
        if (StringUtil.isNull(str) || !StringUtil.null2Str(str).matches(reg)) {
            return false;
        }
        return true;
    }

    /**
     * java判断是否是只有一个字母
     *
     * @param str
     * @return
     */
    public static boolean isOneEnglishCharacters(String str) {
        String reg = "[a-zA-Z]{1}";
        if (StringUtil.isNull(str) || !StringUtil.null2Str(str).matches(reg)) {
            return false;
        }
        return true;
    }

    /**
     * java判断是否为11位手机数字
     *
     * @param str
     * @return
     */
    public static boolean isMobileNumber(String str) {
        String reg = "[\\d]{11}";
        if (StringUtil.isNull(str) || !StringUtil.null2Str(str).matches(reg)) {
            return false;
        }
        return true;
    }

    /**
     * 根据转义列表对字符串进行转义(escape)。
     *
     * @param source        待转义的字符串
     * @param escapeCharMap 转义列表
     * @return 转义后的字符串
     */
    public static String escapeCharacter(String source, @SuppressWarnings("rawtypes") HashMap escapeCharMap) {
        if (source == null || source.length() == 0) {
            return source;
        }

        if (escapeCharMap.size() == 0) {
            return source;
        }

        StringBuilder sb = new StringBuilder(source.length() + 100);
        StringCharacterIterator sci = new StringCharacterIterator(source);
        for (char c = sci.first(); c != StringCharacterIterator.DONE; c = sci.next()) {
            String character = String.valueOf(c);
            if (escapeCharMap.containsKey(character)) {
                character = (String) escapeCharMap.get(character);
            }
            sb.append(character);
        }
        return sb.toString();
    }

    /**
     * 中文转换--文章换行的转换
     *
     * @param str
     * @return
     */

    public static String changeEnter(String str) {
        if (str == null) {
            return ("");
        }
        if (str.equals("")) {
            return ("");
        }
        // 建立一个StringBuilder来处理输入数据
        StringBuilder buf = new StringBuilder(str.length() + 6);
        char ch = '\n';
        for (int i = 0; i < str.length(); i++) {
            ch = str.charAt(i);
            if (ch == '\r') {
                buf.append("|");
            } else if (ch == '\n') {
                buf.append("|");
            } else {
                buf.append(ch);
            }
        }
        return buf.toString();
    }

    /**
     * 截掉url左边的一级目录名,如/wap/news/index.xml -> /news/index.xml
     *
     * @param str
     * @return
     */
    public static String trimLeftNode(String str) {
        if (str == null) {
            return "";
        }

        if (str.startsWith("/")) {
            int ind = str.indexOf('/', 1);
            if (ind > 0) {
                return str.substring(ind);
            }
        }
        return str;
    }

    public static String generatedUrl(List<String> sourceList, String nodestr, int maxint) {
        List<String> nodeList = new ArrayList<>();
        StringBuilder rstr = new StringBuilder();
        try {
            Random rmd = SecureRandom.getInstanceStrong();
            Set<String> cpSet = new HashSet<>();
            Set<Integer> distNum = new HashSet<>();
            Set<String> distCp = new HashSet<>();
            for (int i = 0; i < sourceList.size(); i++) {
                String tmpstr = sourceList.get(i);
                if (getSpstr(tmpstr, 1).equals(nodestr)) {
                    nodeList.add(tmpstr);
                    cpSet.add(getSpstr(tmpstr, 3));
                }
            }
            if (nodeList.size() > maxint) {
                for (int k = 0; k < maxint; k++) {
                    int tmpint = rmd.nextInt(nodeList.size());
                    String tmpstr = nodeList.get(tmpint);
                    boolean firstCheck = distCp.add(getSpstr(tmpstr, 3)) || distCp.size() >= cpSet.size();
                    if (firstCheck && distNum.add(tmpint)) {
                        rstr.append("<a href='" + getSpstr(tmpstr, 4) + "'>");
                        rstr.append(getSpstr(tmpstr, 2) + "</a><br/>");
                    }
                }
            } else {
                for (int j = 0; j < nodeList.size(); j++) {
                    String tmpstr = nodeList.get(j);
                    rstr.append("<a href='" + getSpstr(tmpstr, 4) + "'>");
                    rstr.append(getSpstr(tmpstr, 2) + "</a><br/>");
                }
            }
        } catch (NoSuchAlgorithmException e) {
            log.error("exception: {}", e);
        }
        return rstr.toString();
    }

    public static String getSpstr(String spstr, int level) {
        String rstr = "";
        for (int i = 0; i < level; i++) {
            if (spstr.indexOf("|*") == -1) {
                rstr = spstr;
                return rstr;
            } else {
                rstr = spstr.substring(0, spstr.indexOf("|*"));
            }
            spstr = spstr.substring(spstr.indexOf("|*") + 2, spstr.length());
        }
        return rstr;
    }

    public static String toString(Object obj) {
        try {
            return obj.toString();
        } catch (Exception e) {
            return "";
        }
    }

    private static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
            '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * 把byte[]数组转换成十六进制字符串表示形式
     *
     * @param tmp 要转换的byte[]
     * @return 十六进制字符串表示形式
     */
    public static String byteToHexString(byte[] tmp) {
        if (tmp == null) {
            throw new NullPointerException();
        }
        int len = tmp.length;
        char[] str = new char[len * 2];
        int i = 0;
        for (byte b : tmp) {
            // 取字节中高 4 位的数字转换,
            str[i * 2] = hexDigits[b >>> 4 & 0xf];
            // 取字节中低 4 位的数字转换
            str[i * 2 + 1] = hexDigits[b & 0xf];
            i++;
        }
        return new String(str);
    }

    /**
     * 得到一个String值的指定长度的字符串形式
     * NOTE:	不足的前面添'0'
     *
     * @param s
     * @param len 当s的长度大于len时，截取方式：true,截掉头部；否则从截掉尾部
     *            例如getStringByAppointLen("12345",3,true) ---> "345"
     * @return
     */
    public static String getStringByAppointLen(String s, int len) {
        if (s == null || len <= 0) {
            s = "";
        }

        if (len >= s.length()) {
            return s;
        } else {
            return s.substring(0, len);
        }
    }

    /**
     * 判断是否数字类型
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        try {
            Pattern pattern = compile("[0-9]*");
            Matcher isNum = pattern.matcher(str);
            if (!isNum.matches()) {
                return false;
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return true;
    }

    public static Boolean string2Boolean(String str) {
        try {
            if ("0".equals(str)) {
                return Boolean.FALSE;
            } else if ("1".equals(str)) {
                return Boolean.TRUE;
            } else if ("false".equalsIgnoreCase(str)) {
                return Boolean.FALSE;
            } else if ("true".equalsIgnoreCase(str)) {
                return Boolean.TRUE;
            }
        } catch (Exception e) {
            return Boolean.FALSE;
        }
        return Boolean.FALSE;
    }

    /**
     * 比较版本大小
     *
     * @param s1
     * @param s2
     * @return s1>s2,return=1; s1==s2,return=0;s1<s2,return=-1;
     */
    public static int compare(String s1, String s2) {
        if (s1 == null && s2 == null) {
            return 0;
        } else if (s1 == null) {
            return -1;
        } else if (s2 == null) {
            return 1;
        }

        String[] arr1 = s1.split("[^a-zA-Z0-9]+");
        String[] arr2 = s2.split("[^a-zA-Z0-9]+");

        int i1;
        int i2;
        int i3;
        for (int j = 0, max = Math.min(arr1.length, arr2.length); j <= max; j++) {
            if (j == arr1.length) {
                return j == arr2.length ? 0 : -1;
            } else if (j == arr2.length) {
                return 1;
            }

            try {
                i1 = Integer.parseInt(arr1[j]);
            } catch (Exception x) {
                i1 = Integer.MAX_VALUE;
            }

            try {
                i2 = Integer.parseInt(arr2[j]);
            } catch (Exception x) {
                i2 = Integer.MAX_VALUE;
            }

            if (i1 != i2) {
                return i1 - i2;
            }

            i3 = arr1[j].compareTo(arr2[j]);

            if (i3 != 0) {
                return i3;
            }
        }

        return 0;
    }

    public static String decode(String str) {
        if (StringUtil.isNull(str)) {
            return "";
        }

        try {
            return StringUtil.nullToString(URLDecoder.decode(str, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("exception: {}", e);
        }
        return "";
    }

    public static String encode(String str) {
        if (StringUtil.isNull(str)) {
            return "";
        }

        try {
            return StringUtil.nullToString(URLEncoder.encode(str, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("exception: {}", e);
        }
        return "";
    }

    public static Date strToDate(String strInput, String rDateFormat) {
        Date updateTime = null;
        if (!StringUtil.isNull(strInput)) {
            try {
                SimpleDateFormat formatter = new SimpleDateFormat(rDateFormat);
                formatter.setLenient(false);
                updateTime = formatter.parse(strInput);
            } catch (Exception e) {
                log.error("exception: {}", e);
            }
        }
        return updateTime;
    }

    public static boolean isValidateMobile(String mobile) {
        if (StringUtil.isNull(mobile)) {
            return false;
        }
        Pattern p = compile("^((13[0-9])|(14[0-9])|(15[0-9])|(16[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\\d{8}$");
        Matcher m = p.matcher(mobile);
        return m.matches();
    }

    public static boolean isValidateEmail(String email) {
        if (StringUtil.isNull(email)) {
            return false;
        }
        Pattern p = compile("^[A-Za-z0-9\\u4e00-\\u9fa5]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
        Matcher m = p.matcher(email);
        return m.matches();
    }

    public static String getMobileFromStr(String str) {
        try {
            if (StringUtil.isNull(str)) {
                return null;
            }

            Pattern p = compile("1[3456789]\\d{9}");
            Matcher m = p.matcher(str);
            while (m.find()) {
                return StringUtil.null2Str(m.group());
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return null;
    }

    public static boolean checkSMSCodeValidTime(int validTime, Date createTime) {
        try {
            Long tmpTime = System.currentTimeMillis() - validTime * 60 * 1000;
            if (createTime.getTime() >= tmpTime) {
                return true;
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return false;
    }

    public static String bankCardFormat(String bankCardNumber) {
        String strBankCardNumber = StringUtil.nullToString(bankCardNumber);
        try {
            if (strBankCardNumber != null && strBankCardNumber.length() > 8) {
                strBankCardNumber = strBankCardNumber.substring(0, 4) + "****" + strBankCardNumber.substring(strBankCardNumber.length() - 4);
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return strBankCardNumber;
    }

    public static String mobileFormat(String mobile) {
        String strMobile = StringUtil.nullToString(mobile);
        try {
            if (strMobile != null && strMobile.length() == 11) {
                strMobile = strMobile.substring(0, 3) + "****" + strMobile.substring(7);
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return strMobile;
    }

    public static String identityNoFormat(String identityNo) {
        try {
            if (StringUtil.isValidIdentityCardNO(identityNo)) {
                return identityNo.substring(0, 6) + "********" + identityNo.substring(14).toUpperCase();
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return "";
    }

    public static String shortMobileFormat(String mobile) {
        String strMobile = StringUtil.nullToString(mobile);
        try {
            if (strMobile != null && strMobile.length() == 11) {
                strMobile = strMobile.substring(0, 2) + "**" + strMobile.substring(9);
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return strMobile;
    }

    public static String shortBankCardFormat(String bankCard) {
        String strbankCard = StringUtil.nullToString(bankCard);
        try {
            if (strbankCard != null && strbankCard.length() >= 11) {
                strbankCard = "**" + strbankCard.substring(strbankCard.length() - 4);
            }
        } catch (Exception e) {
            log.error("exception: {}", e);
        }
        return strbankCard;
    }

    public static String getText(String key, Object[] args) {
        if (StringUtil.resourceBundle == null) {
            StringUtil.resourceBundle = ResourceBundle.getBundle(StringUtil.BUNDLE_KEY, Locale.CHINA);
        }
        if (StringUtil.resourceBundle != null) {
            try {
                String result = StringUtil.resourceBundle.getString(key);
                if (result != null) {
                    return MessageFormat.format(result, args);
                } else {
                    return result;
                }
            } catch (Exception e) {
                return key;
            }
        }
        return "";
    }

    public static String getText(String key) {
        return getText(key, null);
    }

    /**
     * 按字节数截取字符串，一个中文长度为2
     *
     * @param str
     * @param subSLength
     * @return
     */
    public static String subStr(String str, int subSLength) {
        if (!StringUtil.isNull(str)) {
            try {
                byte[] bytes = str.getBytes("Unicode");
                int n = 0;
                int i = 2;
                for (; i < bytes.length && n < subSLength; i++) {
                    if (i % 2 == 1) {
                        n++;
                    } else {
                        if (bytes[i] != 0) {
                            n++;
                        }
                    }
                }

                if (i % 2 == 1) {
                    i = i + 1;
                }

                String result = new String(bytes, 0, i, "Unicode");
                if (result.length() < str.length()) {
                    return result + "...";
                } else {
                    return result;
                }
            } catch (Exception e) {
                log.error("exception: {}", e);
            }
        }
        return "";
    }

    /**
     * 服务器上取不到urlencode后的中文参数的问题，需要自己从queryString中解析
     *
     * @param queryString
     * @param paramKey
     * @return
     */
    public static String getQueryStringByKey(String queryString, String paramKey) {
        String paramValue = null;
        if (!StringUtil.isNull(queryString)) {
            Map<String, String> paramMap = new HashMap<>();
            StringTokenizer st = new StringTokenizer(queryString, "&");
            while (st.hasMoreTokens()) {
                String pairs = st.nextToken();
                String key = StringUtil.null2Str(pairs.substring(0, pairs.indexOf('=')));
                String value = StringUtil.null2Str(pairs.substring(pairs.indexOf('=') + 1));
                paramMap.put(key, value);
            }

            if (CollectionUtil.isNotEmpty(paramMap) && paramMap.containsKey(StringUtil.null2Str(paramKey))) {
                paramValue = paramMap.get(paramKey);
            }
        }
        return paramValue;
    }

    /**
     * unicode转成汉字
     *
     * @param unicode
     * @return
     */
    public static String decodeUnicode(Object unicode) {
        String asciiStr = null2Str(unicode);
        if (!isNull(asciiStr)) {
            int i = -1;
            int pos = 0;
            try {
                boolean isNative = false;
                StringBuilder sb = new StringBuilder();
                String tmpString = asciiStr.replace("\\U", "\\u");
                while ((i = tmpString.indexOf("\\u", pos)) != -1) {
                    isNative = true;
                    sb.append(tmpString.substring(pos, i));
                    if (i + 5 < tmpString.length()) {
                        pos = i + 6;
                        sb.append((char) Integer.parseInt(tmpString.substring(i + 2, i + 6), 16));
                    }
                }

                if (isNative) {
                    return sb.toString();
                }
            } catch (Exception e) {
                log.error("exception: {}", e);
            }
        }
        return asciiStr;
    }

    /**
     * 是否有效的身份证
     *
     * @param identityCard
     * @return
     */
    public static boolean isValidIdentityCardNO(String identityCard) {
        identityCard = StringUtil.null2Str(identityCard);
        if (StringUtil.isNull(identityCard) || !IdCardValidatorUtil.isValidatedAllIdcard(identityCard)
                || identityCard.length() != 18) {
            return false;
        }
        return true;
    }

    /**
     * 得到一个String值的指定长度的字符串形式
     * NOTE:	不足的前面添'0'
     *
     * @param s
     * @param len
     * @param cutHead 当s的长度大于len时，截取方式：true,截掉头部；否则从截掉尾部
     *                例如getStringByAppointLen("12345",3,true) ---> "345"
     * @return
     */
    public static String getStringByAppointLen(String s, int len, boolean cutHead) {
        if (s == null || len <= 0) {
            s = "";
        }
        if (len > s.length()) {
            int size = len - s.length();
            StringBuilder sb = new StringBuilder();
            while (size-- > 0) {
                sb.append("0");
            }
            sb.append(s);
            return sb.toString();
        } else if (len == s.length()) {
            return s;
        } else {
            if (cutHead) {
                return s.substring(s.length() - len, s.length());
            } else {
                return s.substring(0, len);
            }
        }
    }

    /**
     * 卡号截取后部，前面以*隐藏
     *
     * @param cordNo
     * @param len
     * @return
     */
    public static String getIndetiryCordNoFomat(String cordNo, int len) {
        if (len > 0 && cordNo.length() > len) {
            for (int i = 0; i < cordNo.length() - len; i++) {
                cordNo = cordNo.replaceFirst(nullToString(cordNo.charAt(i)), "*");
            }
        }
        return cordNo;
    }

    /**
     * 名字超过len长度后显示...
     *
     * @param str
     * @param len
     * @return
     */
    public static String getStringFomat(String str, int len) {
        if (len > 0 && str.length() > len) {
            str = str.substring(0, len) + "...";
        }
        return str;
    }

    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = compile("\\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }


    /**
     * 过滤昵称特殊表情
     */
    public static String filterName(String name) {
        if (name == null) {
            return null;

        }
        if ("".equals(name.trim())) {
            return "";
        }

        Pattern patter = compile("[a-zA-Z0-9\u4e00-\u9fa5]");
        Matcher match = patter.matcher(name);

        StringBuilder buffer = new StringBuilder();

        while (match.find()) {
            buffer.append(match.group());
        }

        return buffer.toString();
    }

    /**
     * 生成随机数字和字母,
     *
     * @param length
     * @return
     */
    public static String getStringRandom(int length) {
        StringBuilder val = new StringBuilder();
        try {
            Random random = SecureRandom.getInstanceStrong();
            //参数length，表示生成几位随机数
            for (int i = 0; i < length; i++) {
                String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
                //输出字母还是数字
                if ("char".equalsIgnoreCase(charOrNum)) {
                    //输出是大写字母还是小写字母
                    int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
                    val.append((char) (random.nextInt(26) + temp));
                } else if ("num".equalsIgnoreCase(charOrNum)) {
                    val.append(String.valueOf(random.nextInt(10)));
                }
            }
        } catch (NoSuchAlgorithmException e) {
            log.error("exception: {}", e);
        }
        return val.toString();
    }

    /**
     * 生成随机数字
     *
     * @param length
     * @return
     */
    public static String getNumberRandom(int length) {
        StringBuilder val = new StringBuilder();
        try {
            Random random = SecureRandom.getInstanceStrong();
            //参数length，表示生成几位随机数
            for (int i = 0; i < length; i++) {
                val.append(String.valueOf(random.nextInt(10)));
            }
        } catch (NoSuchAlgorithmException e) {
            log.error("exception: {}", e);
        }
        return val.toString();
    }
}